package com.zengjianjun.es.demo.highlevelclient.example.service.impl;

import com.zengjianjun.es.demo.common.EsConstant;
import com.zengjianjun.es.demo.entity.EsGaidEntity;
import com.zengjianjun.es.demo.highlevelclient.EsClient;
import com.zengjianjun.es.demo.highlevelclient.example.builder.EsGaidQuery;
import com.zengjianjun.es.demo.highlevelclient.example.service.HLEsGaidService;
import com.zengjianjun.es.demo.highlevelclient.listener.GaidListener;
import com.zengjianjun.es.demo.highlevelclient.options.ConditionOption;
import com.zengjianjun.es.demo.highlevelclient.options.TimeOption;
import com.zengjianjun.es.demo.highlevelclient.param.EsQueryParam;
import com.zengjianjun.es.demo.highlevelclient.param.EsUpdateByQueryParam;
import com.zengjianjun.es.demo.highlevelclient.param.FieldValue;
import com.zengjianjun.es.demo.param.EsGaidParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zengjianjun
 */
@Service
public class HLEsGaidServiceImpl implements HLEsGaidService {

    @Resource
    private EsClient esClient;

    @Override
    public void save(EsGaidEntity entity) {
        esClient.save(EsConstant.INDEX_GAID, entity);
    }

    @Override
    public void saveAll(List<EsGaidEntity> entityList) {
        esClient.save(EsConstant.INDEX_GAID, entityList);
    }

    @Override
    public long countByConditions(EsGaidParam param) {
        return esClient.queryCount(EsConstant.INDEX_GAID, this.getQuery(param));
    }

    @Override
    public List<EsGaidEntity> findList(EsGaidParam param, int from, int size) {
        EsQueryParam esQueryParam = this.getQuery(param);
        return esClient.queryList(EsConstant.INDEX_GAID, esQueryParam, from, size, EsGaidEntity.class);
    }

    @Override
    public void updateCatAndSubCat(EsGaidParam param, String cat, String subCat) {
        EsQueryParam esQueryParam = this.getQuery(param);
        Map<String, Object> updateFieldAndVal = new HashMap<>();
        updateFieldAndVal.put("cat", cat);
        updateFieldAndVal.put("subCat", subCat);
        EsUpdateByQueryParam esUpdateByQueryParam = EsUpdateByQueryParam.builder()
                .index(EsConstant.INDEX_GAID)
                .queryParam(esQueryParam)
                .includes(new String[]{"cat", "subCat"})
                .updateFieldAndVal(updateFieldAndVal)
                .script("ctx._source.cat = params['cat']; ctx._source.subCat = params['subCat'];")
                .listener(GaidListener.build())
                .build();
        esClient.updateByQueryAsync(esUpdateByQueryParam, 6);
    }

    private EsQueryParam getQuery(EsGaidParam param) {
        EsGaidQuery.EsGaidQueryBuilder builder = EsGaidQuery.builder();
        if (StringUtils.isNotEmpty(param.getSource())) {
            builder.source(FieldValue.<String>builder().value(param.getSource()).conditionOption(ConditionOption.equal).build());
        }
        if (StringUtils.isNotEmpty(param.getCountry())) {
            builder.country(FieldValue.<String>builder().value(param.getCountry()).conditionOption(ConditionOption.equal).build());
        }
        if (StringUtils.isNotEmpty(param.getEvent())) {
            builder.event(FieldValue.<String>builder().value(param.getEvent()).conditionOption(ConditionOption.equal).build());
        }
        if (StringUtils.isNotEmpty(param.getPlatform())) {
            builder.platform(FieldValue.<String>builder().value(param.getPlatform()).conditionOption(ConditionOption.equal).build());
        }
        if (StringUtils.isNotEmpty(param.getCat())) {
            builder.cat(FieldValue.<String>builder().value(param.getCat()).conditionOption(ConditionOption.equal).build());
        }
        if (StringUtils.isNotEmpty(param.getSubCat())) {
            builder.subCat(FieldValue.<String>builder().value(param.getSubCat()).conditionOption(ConditionOption.equal).build());
        }
        if (param.getIncludedPkg() != null) {
            builder.includePkg(FieldValue.<List<String>>builder().value(param.getIncludedPkg()).conditionOption(ConditionOption.or).build());
        }
        if (param.getExcludedPkg() != null) {
            builder.excludePkg(FieldValue.<List<String>>builder().value(param.getExcludedPkg()).conditionOption(ConditionOption.or).build());
        }
        if (StringUtils.isNotEmpty(param.getStartCreateTime()) && StringUtils.isNotEmpty(param.getEndCreateTime())) {
            builder.timeOption(TimeOption.builder()
                    .field("createTime")
                    .interval(0)
                    .startTime(param.getStartCreateTime())
                    .endTime(param.getEndCreateTime())
                    .build());
        }
        return builder.build();
    }
}
